﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Modules.Commander.Repositories;
using Modules.System.Security;
using Modules.System.User;
using PmSoft;
using PmSoft.ApplicationContext;
using PmSoft.Entity;
using PmSoft.Exceptions;

namespace Modules.Commander
{
    /// <summary>
    /// 建设单位指挥部业务逻辑
    /// </summary>
    [UseDI(ServiceLifetime.Scoped)]
    public class CommanderService
    {
        private readonly CommanderInfoRepository commanderInfoRepository;
        private readonly IApplicationContext applicationContext;
        private readonly SecurityRepository securityRepository;
        private readonly ILogger logger;

        public CommanderService(CommanderInfoRepository commanderInfoRepository, IApplicationContext applicationContext, SecurityRepository securityRepository, ILogger<CommanderService> logger)
        {
            this.commanderInfoRepository = commanderInfoRepository;
            this.applicationContext = applicationContext;
            this.securityRepository = securityRepository;
            this.logger = logger;
        }

        public void CreateCommander(CommanderInfo commanderInfo, string password)
        {
            if (CodeExists(commanderInfo.Cardno))
                throw new BusinessException($"指挥者:{commanderInfo.Cardno}已存在");

            try
            {
                applicationContext.Transaction.Begin();//开始事务
                SysSecurity security = new();
                security.Password = SecurityPasswordHelper.EncodePassword(password, UserPasswordFormat.SM4);
                security.UserType = UserType.Commander;
                securityRepository.Insert(security);
                commanderInfo.SecurityId = security.SecurityId;//将安全信息表自增主键赋值给用户表
                commanderInfoRepository.Insert(commanderInfo);
                applicationContext.Transaction.Complete();//完成事务
            }
            catch (Exception ex)
            {
                applicationContext.Transaction.Abort();//回滚事务
                logger.LogError(ex, $"CreateConstructor Exception Code:{commanderInfo.Cardno}");
                throw new BusinessException("写入指挥部信息数据失败");
            }
        }

        public bool CodeExists(string code, int? id = null)
        {
            return commanderInfoRepository.CodeExists(code, id);
        }

        public void Update(CommanderInfo commanderInfo)
        {
            commanderInfoRepository.Update(commanderInfo);
        }

        public CommanderInfo? GetCommanderInfo(int commanderId)
        {
            return commanderInfoRepository.Get(commanderId);
        }

        public IEnumerable<CommanderInfo> GetCommanderInfos(IEnumerable<int> ids)
        {
            return commanderInfoRepository.PopulateEntitiesByEntityIds(ids);
        }

        public void UpdateCommander(CommanderInfo commanderInfo)
        {
            if (CodeExists(commanderInfo.Cardno, commanderInfo.CommanderId))
                throw new BusinessException($"指挥者:{commanderInfo.Cardno}已存在");
            commanderInfoRepository.Update(commanderInfo);
        }

        public void UpdatePassword(int id, string password)
        {
            SysSecurity? userSecurity = GetCommanderSecurity(id);
            userSecurity = userSecurity == null ? new SysSecurity() : userSecurity;
            userSecurity.Password = SecurityPasswordHelper.EncodePassword(password, UserPasswordFormat.SM4);
            securityRepository.Update(userSecurity);
        }

        public SysSecurity? GetCommanderSecurity(int commanderId)
        {
            var user = GetCommanderInfo(commanderId);
            if (user == null)
                return null;
            return securityRepository.Get(user.SecurityId);
        }

        public void DeleteCommanderId(int id)
        {
            commanderInfoRepository.DeleteByEntityId(id);
        }

        public void DeleteCommanderIds(IEnumerable<int> ids)
        {
            foreach (var id in ids)
                DeleteCommanderId(id);
        }

        public IPagedList<CommanderInfo> GetCommanders(CommanderQuery query, int pageNum, int pageSize)
        {
            return commanderInfoRepository.GetCommanders(query, pageNum, pageSize);
        }

        public IUser? PasswordSignIn(string cardno, string password)
        {
            var security = GetSecurity(cardno);
            if (security == null)
                throw new BusinessException("指挥部身份证号或密码错误");

            //if (security.Password != password)
            if (!SecurityPasswordHelper.CheckPassword(password, security.Password, UserPasswordFormat.SM4))
                throw new BusinessException("指挥部身份证号或密码错误");
            HandleLogin(security);

            return GetCommanderInfo(cardno);
        }

        public SysSecurity? GetSecurity(string cardno)
        {
            var commanderInfo = GetCommanderInfo(cardno);
            if (commanderInfo == null)
                return null;
            return securityRepository.Get(commanderInfo.SecurityId);
        }

        /// <summary>
        /// 登陆处理
        /// </summary>
        /// <param name="security"></param>
        private void HandleLogin(SysSecurity security)
        {
            securityRepository.UpdateLoginInfoStatus(security, applicationContext.ClientIp, DateTime.Now);
        }

        public CommanderInfo? GetCommanderInfo(string cardno)
        {
            return commanderInfoRepository.GetCommanderInfo(cardno);
        }

        public void UpdateDefaultProjectId(CommanderInfo commanderInfo, int projectId)
        {
            commanderInfoRepository.UpdateDefaultProjectId(commanderInfo, projectId);
        }

        public void Delete(int id)
        {
            commanderInfoRepository.DeleteByEntityId(id);
        }

        public void Deletes(IEnumerable<int> ids)
        {
            foreach (var id in ids)
            {
                Delete(id);
            }
        }
    }
}